package cn.ac.big.bigd.transfer;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.ChannelSftp.LsEntry;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
import java.util.Vector;

public class SFTPUtil {
	private Session sshSession = null;
	private ChannelSftp sftp = null;
	private static Logger logger = Logger.getLogger(SFTPUtil.class);
	
	public boolean connectServer(String server, int port, String user,
			String password,String path) {
		System.out.println("connect server.");
		if (this.sshSession == null) {
			try {

				JSch jsch = new JSch();
				this.sshSession = jsch.getSession(user, server, port);
				sshSession.setPassword(password);
				Properties sshConfig = new Properties();
				sshConfig.put("StrictHostKeyChecking", "no");
				sshSession.setConfig(sshConfig);
				sshSession.connect();
				System.out.println("session connect.");

			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
		}
		if (sftp == null) {
			System.out.println("sftp is null.");
			try {

				Channel channel = sshSession.openChannel("sftp");
				channel.connect();
				System.out.println("channel connect.");
				sftp = (ChannelSftp) channel;
				System.out.println("sftp get.");
				sftp.cd(path);
				System.out.println("Connected to " + server + ".");

			} catch (Exception e) {
				logger.error("ERROR",e);
				return false;
			}
		}

		return true;
	}

	public boolean connectServer(Properties ftpConfig) {

		String host = ftpConfig.getProperty("server");
		int port = 22;
		String user = ftpConfig.getProperty("username");
		String password = ftpConfig.getProperty("password");
		String path = ftpConfig.getProperty("path");
		return connectServer(host,port,user,password,path);
	}


	public boolean changeDiretory(Properties ftpConfig, String path) throws Exception{
		String location = ftpConfig.getProperty("path");
		String newdir = location + "/" + path;
		try{
			sftp.cd(newdir);
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return true;
	}


	public void closeServer() {
		// TODO Auto-generated method stub
		if (sftp != null) {
			sftp.disconnect();
			sftp = null;
		}
		if (sshSession != null) {
			sshSession.disconnect();
			sshSession = null;
		}
	}


	public boolean download(String remoteFileName, String localFileName) {
		// TODO Auto-generated method stub
		try {
			File file = new File(localFileName);
			sftp.get(remoteFileName, new FileOutputStream(file));
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * @param remoteDir
	 * @param localFile
	 * @param sftp
	 */
	public boolean upload(String remoteDir, String localFile,String remoteFile){
		try {
			sftp.cd(remoteDir);
			File file = new File(localFile);
			sftp.put(new FileInputStream(file), remoteFile);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * @param directory
	 * @param downloadFile
	 * @param saveFile
	 * @param sftp
	 */
//	public void download(String directory, String downloadFile,
//			String saveFile, ChannelSftp sftp) {
//		try {
//			sftp.cd(directory);
//			File file = new File(saveFile);
//			sftp.get(downloadFile, new FileOutputStream(file));
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	/**
	 * @param directory
	 * @param deleteFile
	 * @param sftp
	 */
//	public void delete(String directory, String deleteFile, ChannelSftp sftp) {
//		try {
//			sftp.cd(directory);
//			sftp.rm(deleteFile);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	/**
	 * @param dirPath
	 * @param sftp
	 * @return
	 * @throws SftpException
	 */
	public Vector listFiles(String dirPath)
			throws SftpException {
		//synchronized (SFTPUtil.class) {
			System.out.println("dir is:"+dirPath);
			System.out.println("list files.");
			return sftp.ls(dirPath);
		//}
	}
	
	public  boolean mkdir(String dirPath, String dirName){
		//synchronized (SFTPUtil.class) {	
		try
			{
				sftp.cd(dirPath);
				sftp.mkdir(dirName);
				return true;
			}catch(SftpException e){
				e.printStackTrace();
				return false;
			}
		//}
		
	}
	
	
	public boolean mkdirs(String dirPath,String dirName){
		synchronized (SFTPUtil.class) {
		String[] dirStr = dirName.split("/");
		int i=1;
		String curPath = dirPath;
		try{
			while(i<dirStr.length){
				//System.out.println("curpath:"+curPath);
				
				String curDirName = dirStr[i];
				//System.out.println("curDirName:"+curDirName);
				Vector dirList = listFiles(curPath);
				if(!isContainsFile(dirList,curDirName)){
					if(!mkdir(curPath,curDirName)){
						return false;						
					}

				}
					curPath +="/"+curDirName;
					i++;
				
			}
			
		}catch(SftpException e){
			e.printStackTrace();
			return false;
		}
		return true;
		}
	}
	
//	public  boolean mkdirs(String dirPath,String dirName){
//		String[] dirStr = dirName.split("/");
//		int i=1;
//		String curPath = dirPath;
//		try{
//			while(i<dirStr.length){
//				System.out.println("curpath:"+curPath);
//				
//				String curDirName = dirStr[i];
//				System.out.println("curDirName:"+curDirName);
//				Vector dirList = listFiles(curPath);
//				if(!isContainsFile(dirList,curDirName)){
//					if(!mkdir(curPath,curDirName)){
//						return false;						
//					}else{
//						curPath +="/"+curDirName;
//						i++;
//						
//						
//						while(i<dirStr.length){
//							curDirName=dirStr[i];
//							if(!mkdir(curPath,curDirName)){
//								return false;						
//							}
//							curPath +="/"+curDirName;
//							i++;
//						}
//					}
//				}else{
//					curPath +="/"+curDirName;
//					i++;
//				}
//				
//			}
//			
//		}catch(SftpException e){
//			e.printStackTrace();
//			return false;
//		}
//		return true;
//		
//	}
	boolean isContainsFile(Vector fileList,String fileName){
		boolean flag = false;
		for(int i=0;i<fileList.size();i++){
			  LsEntry ls = (LsEntry)fileList.get(i);
			  String dirName = ls.getFilename();
			  System.out.println(dirName);
			  if(fileName.equals(dirName)){
				  flag=true;
				  break;
			  }
				  
			}
		return flag;
	}
	
}
